1. 定义
Ajax 是 Asynchronous JavaScript and XML 的首字母缩写,翻译成中文是”异步 JavaScript 和 XML”。是由大神 Jesse James Garrett 在一篇题为 Ajax: A new Approach to Web Applications的在线文章中提出来的。
这一技术能够在无需刷新页面的情况下,在后台异步地向服务器请求额外的数据,实现更新页面部分内容的目的。传统的网页如果要更新内容必须要刷新整个页面,而且采用的是 “操作,等待,在操作” 的交互模式。
Ajax 并不是一门新的编程语言,它是现有的多种技术的组合。主要包括:
- 浏览器内置的 XMLHttpRequest 对象
- JavaScript 和 HTML DOM
一个典型的应用就是 Google 搜索框,当你在搜索框中输入字符时, JavaScript 会将你输入的字符传到服务器端,服务器返回一个搜索建议的列表。
2. 实现原理
在进入具体细节之间,我们首先来看一下这门技术的实现原理:
- 页面中一个事件处理程序被触发
- 通过 JavaScript 创建一个 XMLHttpRequest 对象
- 浏览器通过 XMLHttpRequest 对象向服务器发送一个请求
- 服务器处理请求并将结果通过 XMLHttpRequest 对象返回给浏览器
- 浏览器提取新数据,利用 DOM 将其插入到页面中
从上面我们不难看出,这门技术实现的第一步就是为页面中某一个节点添加事件处理程序。通过这个事件的触发,来引发后面的一系列操作。这也是 Ajax 为什么能够实现动态交互的原因。
3. XMLHttpRequest 对象
Ajax 技术的核心就是 XMLHttpRequest 对象,浏览器和服务器都通过该对象发送和接收数据。
3.1 创建 XMLHttpRequest 对象
IE7+、 Firefox、 Opera、 Chrome 和 Safari 都支持原生的 XHR 对象,所以,如果不考虑 IE7 之前的版本,大可只用原生的 XHR 对象,如下:
|
但是如果要考虑到 IE7 之前的版本,那么就要做兼容性的处理:
|
3.2 XMLHttpRequest 对象的用法
3.2.1 初始化(启动)及发送
在使用 XHR 对象时,首先必须调用 open 方法将其初始化,它接受三个参数:要发送的请求类型(get、post),接收请求的 URL 和表示是否异步的布尔值。
|
open 方法并不会真正发送请求,而只是启动一个请求以备启动。再调用 send 方法即可发送请求。 send 方法接受一个参数,表示作为请求主体的数据。如果请求类型为 get,那么就必须填 null。
|
当请求发送到服务器端,响应的数据会自动填充 XHR 对象的属性。一共有四个属性:
属性名 | 说明 |
---|---|
status | 响应的 HTTP 状态码 |
statusText | 响应的 HTTP 状态说明 |
responseText | 作为响应主体被返回的文本 |
responseXML | 如果响应主体内容类型不是文本,而是”text/xml”或者”application/xml”,则返回包含响应数据的 XML DOM 文档 |
浏览器接收到响应之后,首先需要检查 status 属性的值,以确定响应已经成功返回。一般以 HTTP 状态码为 200 作为成功的标志。此外,状态码为 304 表示请求的资源并没有被修改,可以直接使用浏览器缓存中的版本,也意味着响应是有效的。
3.2.2 获取、设置头信息
使用 setRequestHeader() 设置单个请求头信息
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");使用 getResponseHeader() 获取单个响应头信息
request.getResponseHeader("Content-Type");使用 getAllResponseHeaders() 获取所有响应头信息
request.getAllResponseHeaders();
3.2.3 同步
|
3.2.4 异步
上面是同步的方法,异步才是我们真正常用的手段。使用异步时,需要触发 readystatechange 事件,然后检测 XHR 对象的 readyState 属性,接着再进行状态码的判断。 readyState 属性表示请求、响应过程的当前活动阶段。有五个值:
值 | 状态 | 说明 |
---|---|---|
0 | 未初始化 | 尚未调用 open() 方法 |
1 | 初始化完成,启动 | 已经调用 open() 方法,但尚未调用 send() 方法 |
2 | 发送 | 已经调用 send() 方法,但尚未接收到响应 |
3 | 接收信息 | 已经接受到部分响应数据 |
4 | 完成接收 | 已经接收到全部响应数据,可以在客户端使用了 |
|
4. GET or POST ?
4.1 GET 请求
GET 是最常见的请求类型,用于向服务器查询某些信息。 必要时,可以将查询字符串参数添加到 URL 的末尾,以便将信息发送给服务器。 对于 XHR,位于传入 open() 方法的 URL 末尾的字符串必须经过正确的编码才行。查询字符串的每个参数的名称和值都要使用 encodeURIComponent() 进行编码,然后才能放到 URL 末尾。而且,所有的名值对都必须用和号(&)分隔。 下面这个函数可以向现有 URL 的末尾添加查询字符串参数:
|
下面是使用这个函数来构建请求 URL 的示例:
|
4.2 POST 请求
使用频率仅次于 GET,通常用于向服务器发送应该被保存的数据。 POST 请求应该把数据作为请求的主体提交。POST 请求的主体可以包含非常多的数据,而且格式不限。 发送 POST 请求的第一步是将 open() 方法的第一个参数设置为 “post”;第二步是向 send() 方法传入数据。
|
5. 封装 Ajax
首先我们要列举一下需要传入该函数的参数:
- url:需要请求资源的地址
- type:请求所采取的方法,get 还是 post
- data:所要传输的数据,一个键值对象
- onsuccess:请求成功时调用的函数
- onfial:请求失败时调用的函数
我们可以将所有的这些参数,以键值对的形式封装成一个对象:
将这个对象最为参数传入到我们封装的 Ajax 函数中,实现如下: